package net.midnighttd.engine.entity.Pathfinder;

import java.util.LinkedList;

/**
 * Author: Adam Scarr
 * Date: 19/04/2009
 * Time: 9:39:52 PM
 *
 * Used for A* Pathfinding.
 */
public class MapNode implements Comparable {
        private int x, y;
        private int g, h;
        private int dx, dy;
        private MapNode from;


        public MapNode(int x, int y, int dx, int dy, MapNode from) {
            this.x = x;
            this.y = y;
            this.dx = dx;
            this.dy = dy;
            if(from != null) {
                this.g = from.g + distanceTo(from.x, from.y);
            }
            this.from = from;
            this.h = distanceTo(dx, dy);
        }

        public boolean equals(Object o) {
            if(!(o instanceof MapNode)) return false;
            MapNode that = (MapNode)o;
            return (x == that.x && y == that.y);
        }

        public int distanceTo(int x, int y) {
            return (Math.abs(dx - x) + Math.abs(dy - y)) * 10;
        }

        public int f() {
            return g + h;
        }

        public Path getPath() {
            if (from != null) {
                Path path = from.getPath();
                path.add(this);
                return path;
            } else {
                return new Path();
            }
        }

        public LinkedList<MapNode> getNeighbors() {
            LinkedList<MapNode> neighbors = new LinkedList<MapNode>();
            neighbors.add(new MapNode(x + 1, y, dx, dy, this));
            neighbors.add(new MapNode(x - 1, y, dx, dy, this));
            neighbors.add(new MapNode(x, y + 1, dx, dy, this));
            neighbors.add(new MapNode(x, y - 1, dx, dy, this));

            return neighbors;
        }

        public int compareTo(Object o) {
            if(!(o instanceof MapNode)) return 0;
            return f() - ((MapNode)o).f();
        }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int G() {
        return g;
    }
}
